﻿using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Oxage.CNC.Models
{
	public class GCodeBlock : IMachineCodeBlock
	{
		#region Constructor
		public GCodeBlock()
		{
			this.inlines = new List<IMachineCodeInline>();
		}

		public GCodeBlock(string block)
		{
			this.inlines = new List<IMachineCodeInline>();
			Parse(block);
		}
		#endregion

		#region Public properties
		public int LineNumber
		{
			get;
			set;
		}
		#endregion

		#region Public methods
		public void Parse(string line)
		{
			//TODO: Find block comment

			//Matches a line of G code
			var match = Regex.Match(line, @"^\s*(?<code>\w[\d\-\+\.]+\s*)*\s*(?<comment>;.*)?$", RegexOptions.IgnoreCase);
			if (match.Success)
			{
				foreach (Capture capture in match.Groups["code"].Captures)
				{
					//Parse and add code (e.g. "G01", "X-.10", "Z+10")
					string code = capture.Value.Trim();
					this.Inlines.Add(new GCodeInline(code));
				}

				if (match.Groups["comment"] != null)
				{
					string comment = match.Groups["comment"].Value;
					this.Inlines.Add(new GCodeInline(comment));
				}
			}
		}

		public override string ToString()
		{
			if (this.Inlines == null)
			{
				return "";
			}

			var builder = new StringBuilder();
			foreach (var inline in this.Inlines)
			{
				if (builder.Length > 0)
				{
					//White space between inlines
					builder.Append(" ");
				}
				builder.Append(inline.ToString());
			}
			return builder.ToString().Trim();
		}
		#endregion

		#region IMachineCodeBlock Members
		private List<IMachineCodeInline> inlines;

		public List<IMachineCodeInline> Inlines
		{
			get
			{
				return this.inlines;
			}
		}

		public void Add(IMachineCodeInline inline)
		{
			this.Inlines.Add(inline);
		}
		#endregion

		#region IEnumerable<IMachineCodeInline> Members
		public IEnumerator<IMachineCodeInline> GetEnumerator()
		{
			return this.inlines.GetEnumerator();
		}
		#endregion

		#region IEnumerable Members
		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.inlines.GetEnumerator();
		}
		#endregion
	}
}
